package com.example.demo.controller;

import com.example.demo.common.ResultAjax;
import com.example.demo.common.SessionUtils;
import com.example.demo.model.ArticleInfo;
import com.example.demo.model.Userinfo;
import com.example.demo.model.vo.UserinfoVO;
import com.example.demo.service.ArticleService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.xml.transform.Result;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Created with IntelliJ IDEA.
 * Description
 * User: 杰
 * Date: 2023 -08 -12
 * Time: 17:51
 */
@RestController
@RequestMapping("/art")
public class ArticleController {
    @Autowired
    private ArticleService articleService;
    // 文章展示时简介的长度
    private static final int _DESC_LENGTH = 100;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private UserService userService;

    // 得到当前登录用户的文章列表
    @RequestMapping("/mylist")
    public ResultAjax myList(HttpServletRequest request) {
        // 1. 获取当前登录用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-1,"当前非登录状态");
        }
        // 2.根据当前用户 id 获取到该用户发表的文章
        List<ArticleInfo> list = articleService.getListByUid(userinfo.getId());
        if (list != null && list.size() > 0) {
            // 多线程的去处理一下简介 (取出前100个字符)
            list.stream().parallel().forEach((art) -> {
                if (art.getContent().length() > _DESC_LENGTH) {
                    art.setContent(art.getContent().substring(0,_DESC_LENGTH));
                }
            });
        }
        // 返回给前端
        return ResultAjax.succ(list);
    }

    // 删除文章
    @RequestMapping("/del")
    public ResultAjax del(Integer aid, HttpServletRequest request) {
        // 先进行参数校验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"参数错误!");
        }
        // 获取当前登录的用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-1,"请先进行登录");
        }
        // 判断文章的归属人并进行删除
        int result = articleService.del(aid,userinfo.getId());
        // 返回结果给前端
        return ResultAjax.succ(result);
    }

    // 添加文章
    @RequestMapping("/add")
    public ResultAjax add(ArticleInfo articleInfo, HttpServletRequest request) {
        // 判读参数是否合法
        if (articleInfo == null || !StringUtils.hasLength(articleInfo.getTitle()) ||
            !StringUtils.hasLength(articleInfo.getContent())) {
            return ResultAjax.fail(-1,"标题或正文为空,请先进行填写");
        }
        // 获取到当前登录的用户id
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            return ResultAjax.fail(-2,"登录状态有误");
        }
        // 将数据存入数据库
        articleInfo.setUid(userinfo.getId());
        int ret = articleService.add(articleInfo);
        // 将结果返回给前端
        return ResultAjax.succ(ret);
    }

    // 查询当前用户发表的文章详情
    @RequestMapping("/update_init")
    public ResultAjax updateInit(Integer aid, HttpServletRequest request) {
        // 参数校验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"参数有误!");
        }
        // 得到当前登录用户 id
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            return ResultAjax.fail(-2,"登录状态有误!");
        }
        // 查询文章并校验权限
        ArticleInfo articleInfo = articleService.getArticleByUidAndId(aid,userinfo.getId());
        if (articleInfo == null) {
            return ResultAjax.fail(-1,"该文章不存在!");
        }
        // 将结果发送给前端
        return ResultAjax.succ(articleInfo);
    }

    // 修改文章内容
    @RequestMapping("/update")
    public ResultAjax update(ArticleInfo articleInfo, HttpServletRequest request) {
        // 参数校验
        if (articleInfo == null || !StringUtils.hasLength(articleInfo.getTitle()) ||
            !StringUtils.hasLength(articleInfo.getContent()) || articleInfo.getId()<=0) {
            return ResultAjax.fail(-1,"参数为空或参数有误!");
        }
        // 获取当前登录的用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            return ResultAjax.fail(-2,"登录状态有误!");
        }
        articleInfo.setUid(userinfo.getId());
        // 修改文章 并校验归属人
        int result = articleService.UpdateByAidAndUid(articleInfo);
        // 将结果返回前端
        return ResultAjax.succ(result);
    }

    // 查询文章详情页
    @RequestMapping("/detail")
    public ResultAjax detail(Integer aid) throws ExecutionException, InterruptedException {
        // 参数校验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1, "非法参数!");
        }
        // 查询文章详情
        ArticleInfo articleInfo = articleService.getDetail(aid);
        if (articleInfo == null || articleInfo.getId() <= 0) {
            return ResultAjax.fail(-1,"非法参数!");
        }
        // 根据 uid 查询用户的详情
        FutureTask<UserinfoVO> userTask = new FutureTask(()->{
            return userService.getUserById(articleInfo.getUid());
        });
        taskExecutor.submit(userTask);
        // 根据 uid 查询用户发表的总文章数
        FutureTask<Integer> artCountTask = new FutureTask<>(()->{
            return articleService.getArtCountByUid(articleInfo.getUid());
        });
        taskExecutor.submit(artCountTask);
        // 等待下面两个任务(线程池)执行完成
        UserinfoVO userinfoVO = userTask.get();
        int artCount = artCountTask.get();

        userinfoVO.setArtCount(artCount);
        HashMap<String, Object> result = new HashMap<>();
        result.put("user",userinfoVO);
        result.put("art",articleInfo);
        // 将数据返回给前端
        return ResultAjax.succ(result);
    }

    @RequestMapping("/increment_rcount")
    public ResultAjax incrementRCount(Integer aid) {
        // 校验参数
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1,"参数有误!");
        }
        // 更改数据库
        int ret = articleService.incrementRCount(aid);
        // 返回结果
        return ResultAjax.succ(ret);
    }

    // 查询分页功能
    @RequestMapping("/getlistbypage")
    public ResultAjax getListByPage(Integer pindex, Integer psize) throws ExecutionException, InterruptedException {
        // 处理参数
        if (pindex == null || pindex < 1) {
            // 如果 pindex < 1, 进行参数校正
            pindex = 1;
        }
        if (psize == null || psize < 1) {
            // 进行参数校正
            psize = 3;
        }
        // 并发进行文章列表和总页数的查询
        // 查询分页数据
        Integer finalPsize = psize;
        Integer finalPindex = pindex;
        FutureTask<List<ArticleInfo>> listTask = new FutureTask<>(() -> {
            int offset = finalPsize * (finalPindex - 1); // 根据这个公式得到 offset
            return articleService.getListByPage(finalPsize,offset);
        });
        // 查询总页数
        FutureTask<Integer> sizeTask = new FutureTask<>(() -> {
            int totalCount = articleService.getCount();
            // 这里算出来的总页数是向上取整。
            return (int) (Math.ceil(totalCount / (finalPsize * 1.0)));
        });
        taskExecutor.submit(listTask);
        taskExecutor.submit(sizeTask);
        // 阻塞等待
        List<ArticleInfo> list = listTask.get();
        int size = sizeTask.get();
        // 组装数据
        HashMap<String,Object> map = new HashMap<>();
        map.put("list",list);
        map.put("size",size);
        // 将结果返回给前端
        return ResultAjax.succ(map);
    }
}
